function [best_Zi, best_acc, Fmin, stage] = Bi_PSO(num_simple, num_iter, num_feature, data_x, data_y, num_lable)
% num_simple:初始化粒子群样本数量;num_iter:搜索迭代次数;num_feature:每个样本包含的特征个数
% data_x代表聚类样本数据,data_y代表聚类样本的标签;num_lable代表聚类样本的标签的种类数
% best_Zi:准确率最高的样本的特征选择情况

% 初始化粒子群样本sample_x:num_simple*num_feature
X = rand(num_simple, num_feature);
% 将X转换成Z
r1 = ones(num_simple, num_feature) * 0.5;
Z = zeros(num_simple, num_feature);
Z(r1 < X) = 1;
Z(r1 >= X) = 0;
pbestz = Z;
% 计算分类准确率F:num_simple*1
F = evaluate(Z, data_x, data_y, num_lable);
pbestf = F;
% 计算gbest,准确率最大的对应的索引
[fmin, gbest] = max(pbestf);
fprintf("iter 0 feature: pbestz(%d,:) fmin: %.4f\n",gbest, fmin);
% 当前位置信息presentx
presentx = rand([num_simple, num_feature]);
% 将presentx转换成presentz
presentz = zeros(num_simple, num_feature);
r2 = ones(num_simple, num_feature) * 0.5;
presentz(r2 < presentx) = 1;
presentz(r2 >= presentx) = 0;
vz = Z;
w = 1;
Fmin = zeros(num_iter, 1);
stage = zeros(num_iter, 1);
for i = 1 : num_iter
    r3 = rand(num_simple, num_feature);
    % pso更新下一步的位置
    vz = w.*vz + 2 * r3 .* (pbestz - presentz) + 2 * r3 .* (pbestz(gbest, :) - presentz);
    % vz设置边界目的是为了使s在0~1之间
    vz(vz > 10) = 10;
    vz(vz < -10) = -10;
    s = 1 ./ (1 + exp(-vz));
    r4 = rand(num_simple, num_feature);
    %r4 = ones(num_simple, num_feature) * 0.5;
    presentz(r4 < s) = 1;
    presentz(r4 >= s) = 0;
    presentf = evaluate(presentz, data_x, data_y, num_lable);
    % 更新每个单独个体最佳位置
    pbestz(presentf > pbestf, :) = presentz(presentf > pbestf, :);
    pbestf(presentf > pbestf, :) = presentf(presentf > pbestf, :);
    % 更新所有个体最佳位置
    [fmin, gbest] = max(pbestf);
    fprintf("iter %d feature: pbestz(%d,:) fmin: %.4f\n",i, gbest, fmin);
    Fmin(i, 1) = fmin;
    stage(i, 1) = sum(pbestz(gbest, :));
%     best_feature = find(pbestz(gbest, :) == 1);
%     disp(sum(pbestz(gbest, :)));
%     disp(best_feature);
end
best_Zi = pbestz(gbest, :);
best_acc = fmin;
end